<template>
  <div class="card content-box">
    <el-form ref="ruleFormRef" :model="ruleForm" :rules="rules" label-width="140px">
      <el-input v-model="ruleForm.id" type="hidden" />

      <el-row :gutter="20">
        <el-col :span="12">
          <el-form-item :label="t('system.menu.parent')" prop="parent_id">
            <el-select-v2
              v-model="ruleForm.parent_id"
              filterable
              remote
              :remote-method="getMenuList"
              :options="Menus"
              :loading="loading"
              placeholder=""
            />
          </el-form-item>

          <el-form-item :label="t('system.menu.title')" prop="title">
            <el-input v-model="ruleForm.title" />
          </el-form-item>

          <el-form-item :label="t('system.menu.icon')" prop="icon">
            <SelectIcon v-model:icon-value="ruleForm.icon" />
          </el-form-item>

          <el-form-item :label="t('system.menu.auth')" prop="auth">
            <el-input v-model="ruleForm.auth" />
          </el-form-item>

          <el-form-item :label="t('system.menu.path')" prop="path">
            <el-input v-model="ruleForm.path" />
          </el-form-item>
          <el-form-item :label="t('system.menu.component')" prop="component">
            <el-input v-model="ruleForm.component" />
          </el-form-item>

          <el-form-item :label="t('system.menu.api')" prop="api">
            <InputTag v-model="ruleForm.api" />
          </el-form-item>

          <el-form-item :label="t('system.menu.note')" prop="note">
            <el-input v-model="ruleForm.note" type="textarea" />
          </el-form-item>
        </el-col>

        <el-col :span="12">
          <el-form-item :label="t('system.menu.type')" prop="type">
            <el-radio-group v-model="ruleForm.type">
              <el-radio :label="item.value" :key="item" v-for="item in typeOptions">{{
                $t(`system.menu.typeNames.${item.label}`)
              }}</el-radio>
            </el-radio-group>
          </el-form-item>

          <el-form-item :label="t('system.menu.link')" prop="is_link">
            <el-input v-model="ruleForm.is_link" />
          </el-form-item>

          <el-form-item :label="t('system.menu.redirect')" prop="redirect">
            <el-input v-model="ruleForm.redirect" />
          </el-form-item>

          <el-form-item :label="t('system.menu.is_full')" prop="is_full">
            <el-radio-group v-model="ruleForm.is_full">
              <el-radio :label="0">{{ $t("common.no") }}</el-radio>
              <el-radio :label="1">{{ $t("common.yes") }}</el-radio>
            </el-radio-group>
          </el-form-item>

          <el-form-item :label="t('system.menu.is_affix')" prop="is_affix">
            <el-radio-group v-model="ruleForm.is_affix">
              <el-radio :label="0">{{ $t("common.no") }}</el-radio>
              <el-radio :label="1">{{ $t("common.yes") }}</el-radio>
            </el-radio-group>
          </el-form-item>

          <el-form-item :label="t('system.menu.is_keep_alive')" prop="is_keep_alive">
            <el-radio-group v-model="ruleForm.is_keep_alive">
              <el-radio :label="0">{{ $t("common.no") }}</el-radio>
              <el-radio :label="1">{{ $t("common.yes") }}</el-radio>
            </el-radio-group>
          </el-form-item>

          <el-form-item :label="t('system.menu.is_hide')" prop="is_hide">
            <el-radio-group v-model="ruleForm.is_hide">
              <el-radio :label="0">{{ $t("system.menu.show") }}</el-radio>
              <el-radio :label="1">{{ $t("system.menu.hide") }}</el-radio>
            </el-radio-group>
          </el-form-item>

          <el-form-item :label="t('system.menu.active_menu')" prop="active_menu" v-show="ruleForm.is_hide > 0 && isButtonOrApi()">
            <el-input v-model="ruleForm.active_menu" />
          </el-form-item>
        </el-col>
      </el-row>

      <el-row :gutter="20">
        <el-form-item>
          <el-button type="primary" @click="submitForm(ruleFormRef)">保存</el-button>
          <el-button @click="resetForm(ruleFormRef)">重置</el-button>
        </el-form-item>
      </el-row>
    </el-form>
  </div>
</template>

<script setup lang="ts" name="menuEdit">
import { reactive, ref, onBeforeMount } from "vue";
import { useI18n } from "vue-i18n";
import { useRoute } from "vue-router";
import type { FormInstance, FormRules } from "element-plus";
import { ElMessage } from "element-plus";
import SelectIcon from "@/components/SelectIcon/index.vue";
import InputTag from "@/components/InputTag/index.vue";
import { menuList, menuCreate, menuUpdate, menuDetail } from "@/api/modules/system";
import { useTabsStore } from "@/stores/modules/tabs";
import { useKeepAliveStore } from "@/stores/modules/keepAlive";

const route = useRoute();
const { t } = useI18n();
const Menus = ref([{ value: 0, label: "顶级路由" }]);

const typeOptions = ref([
  { label: "menu", value: 10 },
  { label: "page", value: 20 },
  { label: "button", value: 30 }
]);

const ruleForm = reactive({
  id: route.params.id,
  type: 10,
  path: "",
  auth: "",
  name: "",
  redirect: "",
  component: "",
  icon: "",
  title: "",
  active_menu: "",
  is_link: "",
  is_hide: 0,
  is_full: 0,
  is_affix: 0,
  is_keep_alive: 0,
  note: "",
  api: "",
  parent_id: 0
});

const tabStore = useTabsStore();
const keepAliveStore = useKeepAliveStore();
const loading = ref(false);

const ruleFormRef = ref<FormInstance>();
//页面必须前端路由地址
const pathIsRequired = (rule: any, value: any, callback: any) => {
  if (ruleForm.type == 20 && !value) {
    return callback(new Error(rule.message));
  }

  callback();
};
//页面必须组件地址
const componentIsRequired = (rule: any, value: any, callback: any) => {
  if (ruleForm.type == 20 && !value) {
    return callback(new Error(rule.message));
  }

  callback();
};
//按钮需要 权限标识
const authtIsRequired = (rule: any, value: any, callback: any) => {
  if (ruleForm.type == 30 && !value) {
    return callback(new Error(rule.message));
  }

  callback();
};

//页面或者按钮需要API接口
const apiIsRequired = (rule: any, value: any, callback: any) => {
  if ((ruleForm.type == 30 || ruleForm.type == 20) && !value) {
    return callback(new Error(rule.message));
  }

  callback();
};

const rules = reactive<FormRules>({
  title: [{ required: true, message: t("system.menu.detail.rule.title"), trigger: "blur" }],
  path: [{ validator: pathIsRequired, message: t("system.menu.detail.rule.path"), trigger: "blur" }],
  component: [{ validator: componentIsRequired, message: t("system.menu.detail.rule.component"), trigger: "blur" }],
  auth: [{ validator: authtIsRequired, message: t("system.menu.detail.rule.auth"), trigger: "blur" }],
  api: [{ validator: apiIsRequired, message: t("system.menu.detail.rule.api"), trigger: "blur" }]
});

const isButtonOrApi = () => {
  return !(ruleForm.type == 30 || ruleForm.type == 40);
};

let timeoutId = null;

const getMenuList = (query?: string) => {
  if (timeoutId) {
    clearTimeout(timeoutId);
  }

  timeoutId = setTimeout(() => {
    loading.value = true;
    menuList({ title: query })
      .then(response => {
        loading.value = false;
        timeoutId = null;
        Menus.value = [];
        if (!query) {
          Menus.value.push({ value: 0, label: "顶级路由" });
        }

        response.data.list.forEach(item => {
          Menus.value.push({ value: Number(item.id), label: item.title });
        });
      })
      .finally(() => {
        loading.value = false;
        timeoutId = null;
      });
  }, 300);
};

const submitForm = async (formEl: FormInstance | undefined) => {
  if (!formEl) return;
  await formEl.validate(valid => {
    if (valid) {
      const action = ruleForm.id > 0 ? menuUpdate : menuCreate;
      ruleForm.is_hide = ruleForm.type == 30 ? 1 : ruleForm.is_hide;
      action(ruleForm).then(response => {
        ElMessage.success(response.message);
        setTimeout(() => {
          if (route.meta.isAffix) return;
          tabStore.removeTabs(route.fullPath);
          keepAliveStore.removeKeepAliveName(route.name as string);
        }, 200);
      });
    } else {
      ElMessage.error(t("common.form_check_error"));
    }
  });
};

const resetForm = (formEl: FormInstance | undefined) => {
  if (!formEl) return;
  formEl.resetFields();
};

const getDetail = (id?: Number) => {
  if (id > 0) {
    menuDetail(route.params).then(response => {
      ruleForm.id = response.data.id;
      ruleForm.type = response.data.type;
      ruleForm.path = response.data.path;
      ruleForm.auth = response.data.auth;
      ruleForm.api = response.data.api;
      ruleForm.name = response.data.name;
      ruleForm.redirect = response.data.redirect;
      ruleForm.component = response.data.component;
      ruleForm.icon = response.data.icon;
      ruleForm.title = response.data.title;
      ruleForm.active_menu = response.data.active_menu;
      ruleForm.is_link = response.data.is_link;
      ruleForm.is_hide = response.data.is_hide;
      ruleForm.is_full = response.data.is_full;
      ruleForm.is_affix = response.data.is_affix;
      ruleForm.is_keep_alive = response.data.is_keep_alive;
      ruleForm.note = response.data.note;
      ruleForm.parent_id = response.data.parent_id;
    });
  }
};

onBeforeMount(() => {
  getDetail(route.params.id);
  getMenuList();
});
</script>

<style scoped lang="scss">
@import "./edit.scss";
</style>
